package com.gitee.genshin.analyse.data;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.file.FileWriter;
import cn.hutool.core.util.StrUtil;
import cn.hutool.db.Db;
import cn.hutool.db.Entity;
import cn.hutool.log.Log;
import com.gitee.genshin.analyse.Main;
import com.gitee.genshin.analyse.data.db.DatabaseConnection;
import com.gitee.genshin.analyse.data.db.DatabaseSource;

import java.io.File;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * @author hongda.li.dlmu@qq.com 2022/7/13 10:15
 */
public abstract class GenshinDataService {
    /**
     * FileWriter是否初始化（祈愿数据分析文件是否需要覆盖）
     */
    private static final AtomicBoolean INIT = new AtomicBoolean(false);
    private static FileWriter writer;
    public final DatabaseConnection CONNECTION = new DatabaseConnection();
    public static final Map<GenshinDataType, List<Integer>> RANK_TYPE5 = new HashMap<>();

    /**
     * 需重写的子服务
     */
    public abstract void doService();

    /**
     * 保存祈愿数据分析记录到本地文件中
     *
     * @param msg    分析数据
     * @param params 数据参数
     */
    public void write(String msg, Object... params) {
        if (!INIT.get()) {
            INIT.set(true);
            writer = new FileWriter(new File(Main.CONFIG.getStr("data.file")));
            writer.write(StrUtil.format(msg, params));
            writer.append("\r\n");
        } else {
            writer.append(StrUtil.format(msg, params));
            writer.append("\r\n");
        }
    }

    /**
     * 通过祈愿类型和祈愿物品级别查询祈愿物品名称
     *
     * @param type     祈愿类型
     * @return 祈愿物品的名称集合
     */
    public List<String> queryData(GenshinDataType type) {
        String sql = "SELECT id, name, time FROM " + DatabaseConnection.TABLE_NAME + " WHERE gacha_type = ? AND rank_type = 5 ORDER BY id";
        List<Entity> result = CONNECTION.find(sql, type.getCode());
        if (CollUtil.isEmpty(result)) {
            return new ArrayList<>();
        }
        List<Integer> countList = new ArrayList<>(result.size());
        List<String> names = new ArrayList<>(result.size());
        for (int i = 0; i < result.size(); i++) {
            // 当前五星的名称
            String name = (String) result.get(i).get("name");
            // 当前抽取时间
            String time = (String) result.get(i).get("time");
            // 当前五星的ID
            long id = (long) result.get(i).get("id");
            // 上一个五星的ID
            long lastId = (i > 0) ? (long) result.get(i - 1).get("id") : 0L;
            String countSql = "SELECT COUNT(*) FROM " + DatabaseConnection.TABLE_NAME + " WHERE ID > ? and ID <= ? and gacha_type = ?";
            // 抽取五星的次数
            int count = CONNECTION.count(countSql, lastId, id, type.getCode());
            countList.add(count);
            // 保存每次抽取五星的次数
            names.add(name + "[第" + count + "次祈愿][" + time.substring(0, 10) + "]");
        }
        RANK_TYPE5.put(type, countList);
        return names;
    }

    /**
     * 查询指定数据是否存在
     *
     * @param id 数据的ID
     * @return 是否存在
     */
    public boolean exists(long id) {
        String sql = "SELECT COUNT(*) FROM " + DatabaseConnection.TABLE_NAME + " WHERE id = ?";
        try {
            Number number = Db.use(DatabaseSource.getDataSource()).queryNumber(sql, id);
            return number != null && number.intValue() != 0;
        } catch (SQLException e) {
            Log.get().error("查询数据出现错误[{}][{}]", sql, e.getMessage());
            throw new RuntimeException(e);
        }
    }

    /**
     * 通过祈愿物品级别查询数量
     *
     * @param rankType 祈愿物品级别
     * @return 此级别下的物品数量
     */
    public int queryRankTypeCount(GenshinRankType rankType) {
        String sql = "SELECT COUNT(*) FROM " + DatabaseConnection.TABLE_NAME + " WHERE rank_type = ?";
        return CONNECTION.count(sql, rankType.getCode());
    }

    /**
     * 查询祈愿数据总数
     *
     * @return 总数量
     */
    public int queryTotal() {
        String sql = "SELECT COUNT(*) FROM " + DatabaseConnection.TABLE_NAME;
        return CONNECTION.count(sql);
    }

    /**
     * 通过祈愿类型查询数量
     *
     * @param type 祈愿类型
     * @return 此祈愿类型的总数量
     */
    public int queryGenshinDataTypeCount(GenshinDataType type) {
        String sql = "SELECT COUNT(*) FROM " + DatabaseConnection.TABLE_NAME + " WHERE gacha_type = ?";
        return CONNECTION.count(sql, type.getCode());
    }

    /**
     * 通过祈愿类型和祈愿物品级别查询数量
     *
     * @param type     祈愿类型
     * @param rankType 祈愿物品级别
     * @return 当前祈愿类型下的，此祈愿物品级别的总数量
     */
    public int queryGenshinDataTypeAndRankTypeCount(GenshinDataType type, GenshinRankType rankType) {
        String sql = "SELECT COUNT(*) FROM " + DatabaseConnection.TABLE_NAME + " WHERE gacha_type = ? AND rank_type = ?";
        return CONNECTION.count(sql, type.getCode(), rankType.getCode());
    }

    /**
     * 通过祈愿类型查询最近一次抽出物品后的抽卡数量
     *
     * @param dataType 祈愿类型
     * @return 最近一次抽出物品后的抽卡数量
     */
    public int queryGenshinDataTypeByOrderCount(GenshinDataType dataType, GenshinRankType rankType) {
        String sql = "select count(*) from genshin_data where gacha_type = ? " +
                "and id > ifnull((select id from genshin_data where rank_type = ? and gacha_type = ? order by id desc limit 1), 0)";
        return CONNECTION.count(sql, dataType.getCode(), rankType.getCode(), dataType.getCode());
    }
}
